﻿using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Linq;
using Microsoft.WindowsAzure.StorageClient;

namespace FLH.RegionDataAllocations
{
	/// <summary>
	/// AllocationsSource maps to the Azure tables and provides the CRUD methods.
	/// </summary>
	public class RegionDataAllocationsSource
	{
		private readonly RegionDataAllocationsServiceContext _projectDataServiceContext;

		/// <summary>
		/// Constructs the datasource. Always checks to see if the table has
		/// previously been created. If not then it creates the table 
		/// using the data context. (NOT recommended for production code.)
		/// </summary>
		public RegionDataAllocationsSource()
		{
			var storageAccount = AzureTableInitialization.GetAccount();
			_projectDataServiceContext = new RegionDataAllocationsServiceContext(storageAccount.TableEndpoint.ToString(),
																				   storageAccount.Credentials);
			//Fixed in Azure				//{
			//    // Optimization: Where table name and class name are not the same
			//    // ResolveEntityType is the name of the method that supplies the object type
			//    // To improve performance of ADO.NET Data Service deserialization 
			//    ResolveType = (unused) => typeof(AllocationsModel)
			//};

		}


		#region READ methods (by Partition, by Partition/Row) http://msdn.microsoft.com/en-us/library/dd894039.aspx

        /// <summary>
        /// Read (select) all rows for a source layer from the client table.
        /// </summary>
        /// <param name="prefix">The prefix.</param>
        /// <returns></returns>
        public IEnumerable<RegionDataAllocationsModel> Read(string prefix)
        {
            if (String.IsNullOrEmpty(prefix)) return null;

            _projectDataServiceContext.MergeOption = MergeOption.NoTracking;	// set when you will not be updating this entity
            IQueryable<RegionDataAllocationsModel> results;
            try
            {
                results = from c in _projectDataServiceContext.AllocationsTable
                          where c.PartitionKey.StartsWith(prefix)
                          select c;
            }
            catch (Exception)
            {
                return null;
            }

            try
            {
                var query = results.AsTableServiceQuery();
                var queryResults = query.Execute();
                return queryResults;
            }
            catch (Exception)
            {
                return null;
            }
        }


        /// <summary>
        /// Read (select) all rows in the specified partition from the client table.
        /// </summary>
        /// <param name="prefix">The prefix.</param>
        /// <returns></returns>
        public IEnumerable<RegionDataAllocationsModel> Read(string prefix, int targetLayerID, int targetRegionID)
        {
            if (String.IsNullOrEmpty(prefix)) return null;
            var partitionKey = prefix + "__" + targetLayerID + "__" + targetRegionID;

            _projectDataServiceContext.MergeOption = MergeOption.NoTracking;	// set when you will not be updating this entity
            IQueryable<RegionDataAllocationsModel> results;
            try
            {
                results = from c in _projectDataServiceContext.AllocationsTable
                          where c.PartitionKey == partitionKey
                          select c;
            }
            catch (Exception)
            {
                return null;
            }

            try
            {
                var query = results.AsTableServiceQuery();
                var queryResults = query.Execute();
                return queryResults;
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
		/// Read (select) the specified row in the specified partition from the client table.
		/// </summary>
		/// <param name="prefix">The prefix.</param>
		/// <param name="targetLayerID">The target layer ID.</param>
		/// <param name="targetRegionID">The target region ID.</param>
		/// <returns></returns>
		public RegionDataAllocationsModel Read(string prefix, int targetLayerID, int targetRegionID, int sourceRegionID)
		{
			if (String.IsNullOrEmpty(prefix)) return null;
            var partitionKey = prefix + "__" + targetLayerID + "__" + targetRegionID;
            var rowKey = sourceRegionID;

			_projectDataServiceContext.MergeOption = MergeOption.NoTracking;	// set when you will not be updating this entity
			RegionDataAllocationsModel results;
			try
			{
				results = (from c in _projectDataServiceContext.AllocationsTable
						   where c.PartitionKey == partitionKey &&
								 c.RowKey == rowKey.ToString()
						   select c).FirstOrDefault();
			}
			catch (Exception)
			{
				return null;
			}

			return results;
		}

		#endregion

	}
}


